import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class MazePeer implements GamePlayerInterface{

	static int DEFAULT_PORT = 30416;
	static String DEFAULT_HOST = "localhost";

	String serverHost;
	int serverPort;

	static String refGameBoard = "GameBoard";
	protected PlayerMovementInfo playerInfo;
	protected int myID;
	protected MazeGameBoard gameboard;
	protected Coordinates initPosition;
	
	public MazePeer() { }

	public MazePeer(String host, int port) {
		serverHost = host;
		serverPort = port;
		playerInfo = new PlayerMovementInfo();
	}
	
	public int getID() {
		return myID;
	}

	public void play() {
		try {
			UnicastRemoteObject.exportObject(this, 0);
			System.out.println("Game Client - host " + serverHost + " port "
					+ serverPort);
			Registry registry = LocateRegistry.getRegistry(serverHost,
					serverPort);

			GameboardInterface stub = (GameboardInterface) registry
					.lookup(refGameBoard);
			GameStatusInfo response = stub.ConnectPlayer(this);
			myID = response.GetPlayerID();
			switch (response.GetGameStatus()) {
			case GAME_IDLE:
				System.out.println("Game Client " + myID
						+ ": gameboard idling, waiting for other players ("
						+ this.initPosition.x + "," + this.initPosition.y + ")");
				this.initPosition = new Coordinates(
						response.GetLastPlayerXCoord(),
						response.GetLastPlayerYCoord());
				break;
			case GAME_STARTING:
				this.initPosition = new Coordinates(
						response.GetLastPlayerXCoord(),
						response.GetLastPlayerYCoord());
				System.out
						.println("Game Client "
								+ myID
								+ ": gameboard starting, waiting for other players at ("
								+ this.initPosition.x + "," + this.initPosition.y
								+ ")");
				break;
			case GAME_STARTED:
				System.out
						.println("Game Client : sorry cannot join. gameboard already started, please come back later ");
				System.exit(0);
				break;
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void ServerStatusUpdate(GameStatusInfo gameStatusInfo)
			throws RemoteException {
		System.out.println("Game Client " + myID +" received from server: "
				+ gameStatusInfo.GetGameStatus().toString());
		if (gameStatusInfo.GetGameStatus() == GameStatusInfo.GameStatus.GAME_STARTED) {
			gameboard = new MazeGameBoard(gameStatusInfo.GetMapSize(),
					this);
		} else if (gameStatusInfo.GetGameStatus() == GameStatusInfo.GameStatus.GAME_IDLE) {
			if (gameboard != null) {
				gameboard.setEndGame();
				gameboard.endGame(gameStatusInfo.playerTreasureCount);
			}
		}
	}
	
	public void move(PlayerMovementInfo.Direction drct) {
		Registry registry;
		try {
			registry = LocateRegistry.getRegistry(serverHost, serverPort);
			GameboardInterface stub = (GameboardInterface) registry
					.lookup(refGameBoard);
			//exception here
			playerInfo.direction =  drct;
			PlayerMovementInfo response = stub.RequestMove(playerInfo, myID);
			System.out.println("Server response the move " + drct.toString());
			gameboard.updateGameBoard(response);
			
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
